﻿using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using QuickCode.Application.DTO.Config;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json.Nodes;
using System.Threading.Tasks;
using Until.Helper;

namespace MyRedis
{
    public class RedisManage:IRedisManage
    {
        public volatile ConnectionMultiplexer _redisConnection;
        private readonly object _redisConnectionLock = new object();
        private readonly ConfigurationOptions _configOptions;
        private readonly ILogger<RedisManage> _logger;
        public RedisManage(ILogger<RedisManage> logger)
        {
            _logger = logger;
            ConfigurationOptions options = ReadRedisSetting();
            if (options == null) _logger.LogError("Redis信息配置有误！");
            this._configOptions = options;
            this._redisConnection = ConnectionRedis();
        }

        /// <summary>
        /// 读取Redis配置信息
        /// </summary>
        /// <returns></returns>
        private ConfigurationOptions ReadRedisSetting()
        {
            try
            {
                List<RedisConfig> config = AppHelper.ReadAppSettings<RedisConfig>(new string[] { "Environment:Redis" }); // 读取Redis配置信息
                if (config.Any())
                {
                    ConfigurationOptions options = new ConfigurationOptions
                    {
                        EndPoints =
                            {
                                {
                                    config.FirstOrDefault().Ip,
                                    config.FirstOrDefault().Port
                                }
                            },
                        ClientName = config.FirstOrDefault().Name,
                        Password = config.FirstOrDefault().Password,
                        ConnectTimeout = config.FirstOrDefault().Timeout,
                        DefaultDatabase = config.FirstOrDefault().Db,
                    };
                    return options;
                }
                return null;
            }
            catch (Exception ex)
            {
                _logger.LogError($"获取Redis配置信息失败：{ex.Message}");
                return null;
            }

        }

        private ConnectionMultiplexer ConnectionRedis()
        {
            if (this._redisConnection != null && this._redisConnection.IsConnected)
            {
                return this._redisConnection; // 已有连接，直接使用
            }
            lock (_redisConnectionLock)
            {
                if (this._redisConnection != null)
                {
                    this._redisConnection.Dispose(); // 释放，重连
                }
                try
                {
                    this._redisConnection = ConnectionMultiplexer.Connect(_configOptions);
                }
                catch (Exception ex)
                {
                    _logger.LogError($"Redis服务启动失败：{ex.Message}");
                }
            }
            return this._redisConnection;
        }

        public string GetValue(string Key)
        {
            return _redisConnection.GetDatabase().StringGet(Key);
        }

        public void Set(string key,object value,TimeSpan ts)
        {
            if (value != null)
            {
                _redisConnection.GetDatabase().StringSet(key, JsonConvert.SerializeObject(value), ts);
            }
        }
    }
}
